package org.simplextensions.ui.settings;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.simplextensions.di.annotations.Point;
import org.simplextensions.di.annotations.Registry;
import org.simplextensions.registry.IExtensionRegistry;
import org.simplextensions.registry.IServiceRegistry;
import org.simplextensions.ui.AutowiredDialog;
import org.simplextensions.ui.SWTApplicationWindow;
import org.simplextensions.ui.ShellAttributesListener;
import org.simplextensions.ui.preferences.IPreferences;
import org.simplextensions.ui.preferences.IPreferencesService;

import java.util.HashMap;
import java.util.Map;

public class SettingsDialog extends AutowiredDialog {

	protected Shell shell;
	private Composite editorParent;
	private Tree tree;

	private StackLayout editorParentStackLayout;

	@Point
	private SettingsExtensionPoint settingsEP;

	@Registry
	private IExtensionRegistry extensionRegistry;

	private IPreferences iPreferences;

	public SettingsDialog(IExtensionRegistry registry, Shell shell, int style) {
		super(registry, shell, style);
		setText(Messages.getString("SettignsDialog.this.text")); //$NON-NLS-1$	
	}

	public SettingsDialog(SWTApplicationWindow applicationWindow) {
		this(applicationWindow.getExtensionRegistry(), applicationWindow.getShell(), SWT.NORMAL);
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public void open() {
		IPreferencesService service = extensionRegistry.getExtensionPoint(IServiceRegistry.class).getService(IPreferencesService.class);
		iPreferences = service.get("SettingsDialog", "SimpleXtensions-UI");
		createContents();

		shell.addControlListener(new ShellAttributesListener(shell, iPreferences));
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		service.save(iPreferences);
	}

	/**
	 * Create contents of the dialog.
	 */
	private void createContents() {
		shell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.MAX | SWT.RESIZE | SWT.APPLICATION_MODAL);
		shell.setSize(640, 480);
		shell.setText(getText());
		GridLayout gl_shell = new GridLayout(1, false);
		gl_shell.marginHeight = 0;
		gl_shell.marginWidth = 0;
		gl_shell.horizontalSpacing = 0;
		gl_shell.verticalSpacing = 0;
		shell.setLayout(gl_shell);

		SashForm composite = new SashForm(shell, SWT.SMOOTH);
		composite.setSashWidth(2);
		composite.setLayout(new GridLayout(1, false));
		GridData gd_composite = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_composite.heightHint = 85;
		composite.setLayoutData(gd_composite);

		Composite treeParent = new Composite(composite, SWT.NONE);
		GridLayout gl_treeParent = new GridLayout(2, false);
		gl_treeParent.verticalSpacing = 0;
		gl_treeParent.marginWidth = 0;
		gl_treeParent.marginHeight = 0;
		gl_treeParent.horizontalSpacing = 0;
		treeParent.setLayout(gl_treeParent);

		Composite composite_2 = new Composite(treeParent, SWT.NONE);
		composite_2.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
		composite_2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		composite_2.setLayout(new GridLayout(1, false));

		tree = new Tree(composite_2, SWT.NONE);
		tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));

		tree.addSelectionListener(new SelectionAdapter() {

			private Map<ASWTSettingsEditor, ISWTSettingsEditorRegion> regionsMap = new HashMap<ASWTSettingsEditor, ISWTSettingsEditorRegion>();

			public void widgetSelected(SelectionEvent arg0) {
				if (tree.getSelectionCount() > 0) {
					SettingsEditorMetaData semd = (SettingsEditorMetaData) tree.getSelection()[0].getData();
					ASWTSettingsEditor editor = (ASWTSettingsEditor) semd.getEditor();
					ISWTSettingsEditorRegion iswtSettingsEditorRegion = regionsMap.get(editor);
					if (iswtSettingsEditorRegion == null) {
						iswtSettingsEditorRegion = new SWTSettingsEditorRegion(new Composite(editorParent, SWT.NORMAL));
						editor.init(iswtSettingsEditorRegion);
						editor.createContents();

						regionsMap.put(editor, iswtSettingsEditorRegion);
					}
					editorParentStackLayout.topControl = iswtSettingsEditorRegion.getClientArea();
					editorParent.layout();
					editorParent.redraw();

					iPreferences.setString("selection", editor.getName());
				}
			}
		});

		Label label_1 = new Label(treeParent, SWT.SEPARATOR);
		label_1.setText(Messages.getString("SettignsDialog.label_1.text")); //$NON-NLS-1$
		label_1.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1));
		label_1.setBounds(0, 0, 49, 13);

		editorParent = new Composite(composite, SWT.NONE);
		editorParentStackLayout = new StackLayout();
		editorParent.setLayout(editorParentStackLayout);
		composite.setWeights(new int[] { 220, 425 });

		Label label = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
		label.setText(Messages.getString("SettignsDialog.label.text")); //$NON-NLS-1$

		Composite composite_1 = new Composite(shell, SWT.NONE);
		GridLayout gl_composite_1 = new GridLayout(2, false);
		gl_composite_1.marginRight = 5;
		composite_1.setLayout(gl_composite_1);
		GridData gd_composite_1 = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_composite_1.heightHint = 43;
		composite_1.setLayoutData(gd_composite_1);

		Button btnZapisz = new Button(composite_1, SWT.NONE);
		GridData gd_btnZapisz = new GridData(SWT.RIGHT, SWT.CENTER, true, true, 1, 1);
		gd_btnZapisz.widthHint = 60;
		btnZapisz.setLayoutData(gd_btnZapisz);
		btnZapisz.setText(Messages.getString("SettignsDialog.btnZapisz.text")); //$NON-NLS-1$

		Button btnCancel = new Button(composite_1, SWT.NONE);
		GridData gd_btnCancel = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1);
		gd_btnCancel.widthHint = 60;
		btnCancel.setLayoutData(gd_btnCancel);
		btnCancel.setText(Messages.getString("SettignsDialog.btnCancel.text")); //$NON-NLS-1$

		String editorID = iPreferences.getString("selection");

		fill();

		if (editorID != null)
			selectItem(editorID, tree.getItems());

	}

	private void selectItem(String editorID, TreeItem[] items) {
		for (TreeItem ti : items) {
			if (editorID.equals(((SettingsEditorMetaData) ti.getData()).getEditor().getName())) {
				tree.setSelection(ti);
				break;
			}
			selectItem(editorID, ti.getItems());
		}
	}

	private void fill() {
		for (SettingsEditorMetaData semd : settingsEP.getSettingsEditors()) {
			addSettingsEditor(null, semd);
		}
	}

	private void addSettingsEditor(TreeItem parent, SettingsEditorMetaData semd) {
		TreeItem treeItem = null;
		if (parent == null)
			treeItem = new TreeItem(tree, SWT.NORMAL);
		else
			treeItem = new TreeItem(parent, SWT.NORMAL);
		treeItem.setData(semd);
		treeItem.setText(semd.getEditor().getName());
		for (SettingsEditorMetaData semd2 : semd.getChildren()) {
			addSettingsEditor(treeItem, semd2);
		}
	}
}
